import numpy as np
import matplotlib.pyplot as plt

def Aproblem(file_path, num_curves=5, colors=None, save_path=None, title=None):
    try:
        # Load data from the file
        data = np.loadtxt(file_path)

        x = data[:, 0]
        y = data[:, 1]

        # Default colors if not provided
        if colors is None:
            colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd']

        f = lambda x: 1 / (1 + 25 * x ** 2)
        plt.figure()

        for i in range(num_curves):
            start_index = i * 2000
            end_index = (i + 1) * 2000

            tempx = x[start_index:end_index]
            tempy = abs(y[start_index:end_index] - f(x[start_index:end_index]))
            plt.plot(tempx, tempy, color=colors[i], linewidth=1.2)
            max_index = np.argmax(tempy)
            max_y = tempy[max_index]
            print(f"The MaxNorm Error is: {max_y:.5f}")


            #plt.plot(x[start_index:end_index], y[start_index:end_index], color=colors[i], linewidth=1.2)


        plt.legend(['N=6', 'N=11', 'N=21', 'N=41', 'N=81'])
        plt.title(title)



        # Generate x_values with the origin at the beginning
        x_values = np.concatenate(([-1], np.linspace(-1, 1, 1999)))
        #plt.plot(x_values, f(x_values), 'k', linewidth=0.8)

        if save_path:
            plt.savefig(save_path, bbox_inches='tight')

        plt.show()

    except FileNotFoundError:
        print(f"Error: File not found at {file_path}")
    except Exception as e:
        print(f"Error: An unexpected error occurred - {e}")

def A_Error() :
    y = np.array([0.42370, 0.02197, 0.00318, 0.00028, 0.00002])
    x = np.array([6, 11, 21, 41, 81])

    # 计算 ln(y) 和 ln(1/(n-1))
    ln_y = np.log(y)
    ln_one_over_n_minus_1 = np.log(1 / (x - 1))

    # 进行线性拟合
    slope, intercept = np.polyfit(ln_one_over_n_minus_1, ln_y, 1)

    # 构建拟合函数的字符串
    fit_equation = f'ln(y) = {slope:.4f} * ln(1/(n-1)) + {intercept:.4f}'

    # 画出 ln(y) 和 ln(1/(n-1)) 的函数关系图
    plt.scatter(ln_one_over_n_minus_1, ln_y, label='Data Points')
    plt.plot(ln_one_over_n_minus_1, slope * ln_one_over_n_minus_1 + intercept, color='red', label='Linear Fit')
    plt.xlabel('ln(1/(N-1))')
    plt.ylabel('ln(error)')
    plt.title('ConvergenceRate')
    plt.legend()

    # 获取坐标范围
    x_range = plt.xlim()
    y_range = plt.ylim()

    # 计算中心坐标
    x_center = (x_range[0] + x_range[1]) / 2
    y_center = (y_range[0] + y_range[1]) / 2

    # 显示拟合函数的表达式在图的中间
    plt.text(x_center, y_center, fit_equation, ha='center', va='center')
    plt.savefig('./Data/result_A_ConvergenceRate', bbox_inches='tight')
    plt.show()

def Cproblem(file_path1, file_path2, colors=None, save_path=None, title=None):
    try:
        data1 = np.loadtxt(file_path1)
        x1 = data1[:, 0]
        y1 = data1[:, 1]
        data2 = np.loadtxt(file_path2)
        x2 = data2[:, 0]
        y2 = data2[:, 1]

        if colors is None:
            colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd']
        f = lambda x: 1 / (1 + x ** 2)

        plt.figure()

        x_values = np.linspace(-5, 5, 1000)
        plt.plot(x1, y1, 'r')
        plt.plot(x2, y2, 'g')
        plt.plot(x_values, f(x_values), 'k', linewidth=0.8)

        plt.legend(['Cubic', 'Quardratic', '1/(1+x²)'])
        plt.title('bSpline')

        if save_path:
            plt.savefig(save_path, bbox_inches='tight')
        plt.show()


        plt.figure()
        plt.plot(x1, abs(y1 - f(x1)), 'r')
        plt.plot(x2, abs(y2 - f(x2)), 'b')
        plt.savefig('./Data/result_C_error.jpg', bbox_inches='tight')
        plt.show()

    except FileNotFoundError:
        print(f"Error: File not found at {file_path1}")
    except Exception as e:
        print(f"Error: An unexpected error occurred - {e}")

def Eproblem(file_path1, file_path2, file_path3, colors=None, save_path=None, title=None):
    try:
        data1 = np.loadtxt(file_path1)
        x1 = data1[:, 0]
        y1 = data1[:, 1]
        data2 = np.loadtxt(file_path2)
        x2 = data2[:, 0]
        y2 = data2[:, 1]
        data3 = np.loadtxt(file_path3)
        x3 = data2[:, 0]
        y3 = data2[:, 1]

        t_values = np.arange(-np.pi / 2, 1.5 * np.pi, 0.0001 * np.pi)
        x_values = np.sqrt(3) * np.cos(t_values)
        y_values = (2 / 3) * np.sqrt(3) * np.sin(t_values) + (2 / 3) * np.sqrt(np.sqrt(3) * np.abs(np.cos(t_values)))

        if colors is None:
            colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd']
        plt.figure()

        plt.plot(x1, y1, '#A52A2A', linewidth=1.2)
        plt.plot(x3, y3, '#FFA500', linewidth=2)
        plt.plot(x2, y2, 'b', linewidth=1.2)
        plt.plot(x_values, y_values, '#000000')
        plt.legend(['N=10', 'N=40', 'N=160', 'heart'])
        plt.title('Cubic Bspline')

        if save_path:
            plt.savefig(save_path, bbox_inches='tight')
        plt.show()

    except FileNotFoundError:
        print(f"Error: File not found at {file_path1}")
    except Exception as e:
        print(f"Error: An unexpected error occurred - {e}")


file_path1 = './Data/result_A_1.txt'
file_path2 = './Data/result_A_2.txt'
file_path3 = './Data/result_A_3.txt'
file_path4 = './Data/result_C_cubic.txt'
file_path5 = './Data/result_C_quad.txt'
file_path6 = './Data/N =10CubicBspline.txt'
file_path7 = './Data/N =40CubicBspline.txt'
file_path8 = './Data/N =160CubicBspline.txt'
#
distinct_colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd']
np.random.shuffle(distinct_colors)
A_Error()
Aproblem(file_path1, colors=distinct_colors, save_path='./Data/result_A_Com_error.jpg', title= 'Aproblem_com')
np.random.shuffle(distinct_colors)
Aproblem(file_path2, colors=distinct_colors, save_path='./Data/result_A_D2_error.jpg', title= 'Aproblem_D2')
np.random.shuffle(distinct_colors)
Aproblem(file_path3, colors=distinct_colors, save_path='./Data/result_A_Nat_error.jpg', title= 'Aproblem_Nua')
Cproblem(file_path4, file_path5,colors=distinct_colors, save_path='./Data/result_C.jpg')
Eproblem(file_path6, file_path7, file_path8, save_path='./Data/result_E.jpg')


